{"record":{"id":"c677f163b6b96e91","repo":"paperclipai/paperclip","slug":"challenge-secret-is-required-pass-token-or-to","errorCode":null,"errorMessage":"Challenge secret is required. Pass --token or --token-env.","messagePattern":"Challenge secret is required\\. Pass --token or --token-env\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cli/src/commands/client/auth.ts","lineNumber":202,"sourceCode":"        }),\n    );\n  }\n}\n\nfunction parseJson(value: string): unknown {\n  return JSON.parse(value) as unknown;\n}\n\nfunction resolveChallengeToken(opts: AuthChallengeOptions): string {\n  const token = opts.token?.trim();\n  if (token) return token;\n  const envName = opts.tokenEnv?.trim();\n  if (envName) {\n    const envValue = process.env[envName]?.trim();\n    if (envValue) return envValue;\n    throw new Error(`Environment variable ${envName} is empty or not set.`);\n  }\n  throw new Error(\"Challenge secret is required. Pass --token or --token-env.\");\n}\n","sourceCodeStart":184,"sourceCodeEnd":204,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/cli/src/commands/client/auth.ts#L184-L204","documentation":"HTTP 404 with body {\"error\":\"User secret definition not found\"} from DELETE /api/companies/:companyId/user-secret-definitions/:definitionId (secrets.ts:691). svc.removeUserSecretDefinition(companyId, definitionId, ...) returned null: no definition matched the company+ID pair at removal time - already deleted, wrong company, or bad ID. Requires secret-definition admin rights.","triggerScenarios":"Double-delete of the same definition; deleting a definition whose ID was copied from another company; cleanup jobs re-running after a partial failure where the first pass already removed it.","commonSituations":"Idempotency-unaware deprovisioning scripts; multi-company admins pasting a definitionId under the wrong :companyId; UI retry of a delete that actually succeeded.","solutions":["Treat 404 on DELETE as 'already gone' when removal is the goal (idempotent semantics).","Derive deletion targets from a fresh list call scoped to :companyId, not from stored IDs.","Confirm the actor holds secret-definition admin in that company before scripting bulk deletes.","Verify :companyId and definitionId pair correctness when copying between environments."],"exampleFix":"// before\nconst res = await api.delete(`/api/companies/${companyId}/user-secret-definitions/${defId}`);\nif (!res.ok) throw new Error('delete failed');\n\n// after\nconst res = await api.delete(`/api/companies/${companyId}/user-secret-definitions/${defId}`);\nif (res.status === 404) {\n  logger.info(`definition ${defId} already absent in ${companyId}; done`);\n} else if (!res.ok) {\n  throw new Error(`delete failed: ${res.status}`);\n}","handlingStrategy":"fallback","validationCode":"async function deleteDefinitionSafe(api: ApiClient, companyId: string, definitionId: string) {\n  const res = await api.fetch(`/api/companies/${companyId}/user-secret-definitions/${definitionId}`, {\n    method: 'DELETE',\n  });\n  if (res.status === 404) return { deleted: true, alreadyGone: true };\n  if (!res.ok) throw new Error(`delete failed: ${res.status}`);\n  return { deleted: true, alreadyGone: false };\n}","typeGuard":"function isApiErrorBody(body: unknown): body is { error: string } {\n  return typeof body === 'object' && body !== null &&\n    typeof (body as Record<string, unknown>).error === 'string';\n}\nconst isDefinitionNotFound = (b: unknown): boolean =>\n  isApiErrorBody(b) && b.error === 'User secret definition not found';","tryCatchPattern":"try {\n  await api.delete(`/api/companies/${companyId}/user-secret-definitions/${defId}`);\n} catch (err) {\n  if (err instanceof ApiError && err.status === 404 && isDefinitionNotFound(err.body)) {\n    return; // already removed - idempotent success\n  }\n  throw err;\n}","preventionTips":["Treat definition DELETE 404 as success in deprovisioning scripts.","Derive deletion targets from a fresh, company-scoped list call.","Match :companyId to the definition's real owner when copying IDs.","Make UI delete actions idempotent (disable after click, ignore follow-up 404s)."],"tags":["http-404","express","secrets","user-secret-definitions","delete","idempotency","paperclip"],"backgroundTag":"http-404-resource-not-found","analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}