ComposioHQ/composio · warning
Forbidden
Error message
Forbidden
What it means
In the local permissions HTTP server, requests whose token query parameter does not match the expected per-session token receive a 403 response body 'Forbidden'. This is a plain HTTP response, not a thrown error, and exists to prevent unauthorized local processes from approving/denying tool permissions.
Source
Thrown at ts/packages/cli/src/services/tool-permissions.ts:979
readonly toolSlug: string;
readonly accountLabel?: string;
readonly agent: NativeUiCallerAgent;
}): Promise<PermissionDecision> =>
new Promise((resolve, reject) => {
const token = crypto.randomUUID();
let settled = false;
const settle = (decision: PermissionDecision) => {
if (settled) return;
settled = true;
server.close();
resolve(decision);
};
const server = http.createServer((req, res) => {
const url = new URL(req.url ?? '/', 'http://127.0.0.1');
if (url.searchParams.get('token') !== token) {
res.writeHead(403, { 'Content-Type': 'text/plain; charset=utf-8' }).end('Forbidden');
return;
}
if (url.pathname === '/') {
res
.writeHead(200, {
'Content-Type': 'text/html; charset=utf-8',
'Cache-Control': 'no-store',
})
.end(approvalHtml({ ...params, token }));
return;
}
const decision =
url.pathname === '/allow-session'
? 'allow_session'
: url.pathname === '/allow-once'
? 'allow_once'View on GitHub (pinned to 64b1b85502)
Solutions
- Use the fresh approval URL printed by the current CLI run
- If the link came from an older session, restart the run to get a new link/token
- Ensure the URL, including the token query parameter, is copied intact
Defensive patterns
Strategy: fallback
Prevention
- Always use the approval URL emitted by the current run
- Copy the full URL including ?token=...
- Discard approval links from prior sessions
When it happens
Trigger: A browser or local process hitting the permission callback server URL with a missing, wrong, or stale ?token= value — e.g. opening an old approval link after the server restarted (new token), or a mangled URL copy.
Common situations: Reusing a stale approval link from a previous run, URL truncation when copying, or another local app probing the port. The server binds locally and gates every path behind the token check.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Not found
- HTTP ${response.status} ${response.statusText}
- File not readable: {file}. Please check the file permissions
- Refusing to fetch: too many redirects (max {max_redirects})
- Failed to fetch file: ${response.statusText}
AI-assisted analysis of ComposioHQ/composio@64b1b85502 (2026-08-28).
Data as JSON: /api/errors/2b85d94587d41f52.
Report an issue: GitHub.