{"record":{"id":"8a01fd556a5108f2","repo":"paperclipai/paperclip","slug":"timeline-is-outside-this-actor-s-authorization-bou","errorCode":null,"errorMessage":"Timeline is outside this actor's authorization boundary","messagePattern":"Timeline is outside this actor's authorization boundary","errorType":"http","errorClass":null,"httpStatus":403,"severity":"error","filePath":"server/src/routes/companies.ts","lineNumber":436,"sourceCode":"  });\n\n  router.get(\"/:companyId/artifacts\", async (req, res) => {\n    const companyId = req.params.companyId as string;\n    assertCompanyAccess(req, companyId);\n    const query = companyArtifactsQuerySchema.parse(req.query);\n    res.json(await artifacts.list(companyId, query, {\n      userId: query.starred && req.actor.type === \"board\" ? req.actor.userId : undefined,\n    }));\n  });\n\n  router.get(\"/:companyId/timeline\", async (req, res) => {\n    const companyId = req.params.companyId as string;\n    assertCompanyAccess(req, companyId);\n\n    const companyScopeDecision = await access.decide({\n      actor: req.actor,\n      action: \"company_scope:read\",\n      resource: { type: \"company\", companyId },\n    });\n    if (!companyScopeDecision.allowed) {\n      res.status(403).json({ error: \"Timeline is outside this actor's authorization boundary\" });\n      return;\n    }\n\n    const query = timelineQuerySchema.parse(req.query);\n    const timeline = workTimelineService(db);\n    const result = await timeline.getTimeline({\n      companyId,\n      from: parseDateQuery(query.from, \"from\"),\n      to: parseDateQuery(query.to, \"to\"),\n      userId: query.userId,\n      goalId: query.goalId,\n      projectId: query.projectId,\n      issueId: query.issueId,\n      limit: parseIntegerQuery(query.limit, \"limit\"),\n      offset: parseIntegerQuery(query.offset, \"offset\"),","sourceCodeStart":418,"sourceCodeEnd":454,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/server/src/routes/companies.ts#L418-L454","documentation":"Authorization gate on GET /companies/:companyId/timeline: the 'company_scope:read' access decision for this company was denied, so the actor may not read the company-wide timeline and the route withholds it with 403.","triggerScenarios":"Thrown at server/src/routes/companies.ts:404 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["This is an authorization rule, not a bug: perform the action with an actor that satisfies the stated constraint (board user, the owning agent, or an in-scope resource).","If access should be allowed, verify the actor's credentials/company scope and the resource's ownership before retrying."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}