---
title: Troubleshooting
description: The errors shebang-mcp tools actually raise, and what to do about each one.
---

# Troubleshooting

## "missing API key" or a 401 from any tool

Every tool call needs a credential — an `shb_…` key (local server) or
either an `shb_…` key or a sherlock OAuth token (hosted server, see
[hosted MCP](/mcp/hosted-mcp)). If a call fails with something like
"missing API key" or `401`/`invalid_api_key`, log in again:

```
npx -y shebang-mcp login
```

This starts a fresh device-login flow (see [device login](/getting-started/device-flow-login)):
it prints a code and a URL, tries to open a browser, and polls until a
human approves it. On approval it writes the new key locally and every
future tool call in this server (or any other harness pointed at the
same machine) picks it up automatically.

## 401 vs. 403 insufficient_scope

These mean different things — don't treat them the same:

- **`401`** — the credential itself is missing, unrecognized, expired, or
  revoked. Nothing about it is trusted at all; log in again.
- **`403 insufficient_scope`** — the credential is valid, but doesn't
  cover this call: an app key missing the needed `apps` scope, a key or
  token trying to reach a project it isn't homed in or granted onto, or
  a master-only tool (`key_*`, `oauth_*`, `email_send`) called with an
  app key. Naming a project a key can't reach fails this way too — never
  a not-found error, so a project's existence is never leaked to a
  credential that can't reach it. The fix here isn't logging in again;
  it's a different key, or a grant (`project_grant_key`) onto the
  project you're targeting.

## project_create / project_set: 400 on color

`color` is a curated enum, not an arbitrary hex value — passing anything
else 400s. The accepted values are exactly: `#ef4444`, `#f97316`,
`#f59e0b`, `#84cc16`, `#22c55e`, `#14b8a6`, `#06b6d4`, `#3b82f6`,
`#6366f1`, `#8b5cf6`, `#a855f7`, `#ec4899`. Both tools reject a value
outside this list client-side, before any network call, and list the
full set in the error.

## store_upload_content: 415 unsupported file type

`store_upload_content` (the hosted server's upload tool — see
[hosted MCP](/mcp/hosted-mcp)) has no local file to read an extension
from, so the platform infers the content type from `path`'s extension
alone, never from `contentType`. If `path` is missing an extension (or
omitted entirely — it falls back to `slug`, which is rarely a
recognizable extension), the upload 415s. Add a real extension to
`path` (e.g. `"notes.txt"` rather than `"notes"`), or rely on the
tool's own client-side fallback: for a handful of common
`contentType` values (`image/png`, `image/jpeg`, `image/gif`,
`image/webp`, `image/svg+xml`, `text/plain`,
`application/json`, `application/pdf`, `video/mp4`, `audio/mpeg`) it
appends the matching extension itself before ever calling the platform.
Anything outside that list needs an explicit extension in `path`.

sherserve does not host HTML — there's no `contentType` value or
`path` extension that gets an HTML upload past this 415. Publish HTML
with [`sherpage_publish`](/sherpage/publishing) instead.

## base_run_sql: one statement per call

`base_run_sql` runs exactly one SQL statement per call — it isn't a
multi-statement script runner. Split a migration or setup script into
one `base_run_sql` call per statement.

## Next

[Tools reference](/mcp/tools-reference) — every tool's real arguments,
including which ones need `confirm` and what it must equal.
