{"record":{"id":"625edf9f1074cf73","repo":"paperclipai/paperclip","slug":"board-access-is-required-to-resolve-companies-acro","errorCode":null,"errorMessage":"Board access is required to resolve companies across the instance. Use a company ID/prefix for your current company, or run with board authentication.","messagePattern":"Board access is required to resolve companies across the instance\\. Use a company ID/prefix for your current company, or run with board authentication\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/company.ts","lineNumber":1968,"sourceCode":"\n          if (!target && ctx.companyId) {\n            const scoped = await ctx.api.get<Company>(apiPath`/api/companies/${ctx.companyId}`, { ignoreNotFound: true });\n            if (scoped) {\n              try {\n                target = resolveCompanyForDeletion([scoped], normalizedSelector, by);\n              } catch {\n                // Fallback to board-wide lookup below.\n              }\n            }\n          }\n\n          if (!target) {\n            try {\n              const companies = (await ctx.api.get<Company[]>(\"/api/companies\")) ?? [];\n              target = resolveCompanyForDeletion(companies, normalizedSelector, by);\n            } catch (error) {\n              if (error instanceof ApiRequestError && error.status === 403 && error.message.includes(\"Board access required\")) {\n                throw new Error(\n                  \"Board access is required to resolve companies across the instance. Use a company ID/prefix for your current company, or run with board authentication.\",\n                );\n              }\n              throw error;\n            }\n          }\n\n          if (!target) {\n            throw new Error(`No company found for selector '${normalizedSelector}'.`);\n          }\n\n          assertDeleteConfirmation(target, opts);\n\n          await ctx.api.delete<{ ok: true }>(apiPath`/api/companies/${target.id}`);\n\n          printOutput(\n            {\n              ok: true,","sourceCodeStart":1950,"sourceCodeEnd":1986,"githubUrl":"https://github.com/paperclipai/paperclip/blob/67001ec6eb96ae601aa27bc91d9b2415d665334a/cli/src/commands/client/company.ts#L1950-L1986","documentation":"Thrown when the fallback board-wide GET /api/companies fails with a 403 whose message contains 'Board access required'. This path is reached only after company-scoped lookups failed to find a target, so the CLI attempted an instance-wide listing that agent-scoped credentials cannot access. The error message tells the caller board auth is needed for cross-instance resolution.","triggerScenarios":"Authenticated with an agent API key (scoped to one company), selector did not match the scoped company, and the CLI fell back to GET /api/companies which returns 403 for non-board tokens.","commonSituations":"Agent automation running `company delete` with a selector outside its own company; CI using an agent key to clean up companies created by other agents; no board token configured.","solutions":["Use a board/instance-admin token: run `paperclipai connect` as a board persona or set a board API key.","Restrict the selector to the agent's own company (use its ID or prefix) so the board-wide lookup is never needed.","Resolve the company ID first via `paperclipai company current --json` and pass `--by id`."],"exampleFix":"# before (agent key, cross-company selector)\nexport PAPERCLIP_API_KEY=$AGENT_KEY\npaperclipai company delete otherco --yes --confirm OTHER\n# after (board token)\nexport PAPERCLIP_API_KEY=$BOARD_KEY\npaperclipai company delete otherco --yes --confirm OTHER","handlingStrategy":"try-catch","validationCode":"// Detect board-access requirement before triggering the board-wide lookup.\nfunction tokenIsBoardScoped(profile: { persona?: string }): boolean {\n  return profile.persona === \"board\";\n}\n// If not board-scoped, restrict the selector to the agent's own company to avoid the fallback.","typeGuard":"import { ApiRequestError } from \"../../client/http.js\";\n\nfunction isBoardAccess403(err: unknown): boolean {\n  return err instanceof ApiRequestError && err.status === 403 && err.message.toLowerCase().includes(\"board access required\");\n}","tryCatchPattern":"try {\n  const companies = await ctx.api.get<Company[]>(\"/api/companies\");\n} catch (err) {\n  if (isBoardAccess403(err)) {\n    throw new Error(\"Switch to a board token or restrict the selector to the agent's own company.\");\n  }\n  throw err;\n}","preventionTips":["Use board tokens for cross-company operations; agent keys for scoped ones.","For agent automation, always pass an explicit company-scoped selector to avoid the board fallback.","Document which commands require board auth."],"tags":["cli","company-delete","authorization","forbidden","board-access"],"backgroundTag":null,"analyzedSha":"67001ec6eb96ae601aa27bc91d9b2415d665334a","analyzedAt":"2026-08-12T12:05:45.408Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}