{"record":{"id":"af55c917c24efa8b","repo":"paperclipai/paperclip","slug":"workspace-file-path-is-denied-by-policy","errorCode":null,"errorMessage":"Workspace file path is denied by policy","messagePattern":"Workspace file path is denied by policy","errorType":"http","errorClass":"HttpError","httpStatus":403,"severity":"error","filePath":"server/src/services/workspace-file-resources.ts","lineNumber":332,"sourceCode":"  if (lowerSegments.some((segment) => DENIED_SEGMENTS.has(segment))) return \"denied_path_segment\";\n\n  const fileName = lowerSegments.at(-1) ?? \"\";\n  if (fileName === \".env\" || fileName.startsWith(\".env.\")) return \"denied_secret\";\n  if (fileName.endsWith(\".pem\") || fileName.endsWith(\".key\") || fileName.endsWith(\".p12\") || fileName.endsWith(\".pfx\")) {\n    return \"denied_secret\";\n  }\n  if ([\"id_rsa\", \"id_ed25519\", \".npmrc\", \".pypirc\", \".netrc\", \"kubeconfig\"].includes(fileName)) return \"denied_secret\";\n  if (lowerSegments.includes(\".aws\") || lowerSegments.includes(\".ssh\")) return \"denied_secret\";\n  if (lowerSegments.length >= 2 && lowerSegments.at(-2) === \".docker\" && fileName === \"config.json\") return \"denied_secret\";\n  if (lowerSegments.length >= 2 && lowerSegments.at(-2) === \".kube\" && fileName === \"config\") return \"denied_secret\";\n\n  return null;\n}\n\nfunction throwIfDenied(segments: string[]) {\n  const denialReason = denyReasonForPathSegments(segments);\n  if (denialReason) {\n    throw new HttpError(403, \"Workspace file path is denied by policy\", { code: denialReason });\n  }\n}\n\nfunction shouldPruneSegments(segments: string[]) {\n  return denyReasonForPathSegments(segments) != null;\n}\n\nfunction contentTypeForPath(filePath: string): string | null {\n  const ext = path.extname(filePath).toLowerCase();\n  if (IMAGE_CONTENT_TYPES.has(ext)) return IMAGE_CONTENT_TYPES.get(ext) ?? null;\n  if (VIDEO_CONTENT_TYPES.has(ext)) return VIDEO_CONTENT_TYPES.get(ext) ?? null;\n  if (ext === \".pdf\") return \"application/pdf\";\n  if (ext === \".svg\") return \"image/svg+xml\";\n  if (ext === \".html\" || ext === \".htm\") return \"text/html\";\n  if (TEXT_EXTENSIONS.has(ext)) return \"text/plain; charset=utf-8\";\n  return null;\n}\n","sourceCodeStart":314,"sourceCodeEnd":350,"githubUrl":"https://github.com/paperclipai/paperclip/blob/120ae5428fa29bee300bcf806491cd4d965fbb7c/server/src/services/workspace-file-resources.ts#L314-L350","documentation":"throwIfDenied policy guard: the workspace path matches a deny rule — a denied path segment, a secrets file (.env*, *.pem/*.key/*.p12/*.pfx, id_rsa, .npmrc, .netrc, kubeconfig...), or traversal through .aws/.ssh. The 422 prevents agents from reading credential material from workspaces regardless of filesystem permissions; choose a non-secret path.","triggerScenarios":"Thrown at server/src/services/workspace-file-resources.ts:332 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The path matches a deny rule (e.g. .env, key files). Choose an allowed path or adjust the workspace file policy."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"120ae5428fa29bee300bcf806491cd4d965fbb7c","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}