{"record":{"id":"d4c3924f71492d31","repo":"multica-ai/multica","slug":"invalid-token","errorCode":null,"errorMessage":"invalid token","messagePattern":"invalid token","errorType":"http","errorClass":null,"httpStatus":401,"severity":"error","filePath":"server/internal/middleware/auth.go","lineNumber":75,"sourceCode":"\t\t\tif fromCookie && !auth.ValidateCSRF(r) {\n\t\t\t\tslog.Debug(\"auth: CSRF validation failed\", \"path\", r.URL.Path)\n\t\t\t\thttp.Error(w, `{\"error\":\"CSRF validation failed\"}`, http.StatusForbidden)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// Agent task token: \"mat_\" prefix. Minted by the server at\n\t\t\t// task-claim time and injected by the daemon into the agent\n\t\t\t// process. Authoritative for actor identity — the bound\n\t\t\t// (user_id, agent_id, task_id, workspace_id) triple is\n\t\t\t// written into request headers here, OVERRIDING whatever the\n\t\t\t// client sent, so a downstream actor-resolver cannot be\n\t\t\t// tricked by a client that strips or forges X-Agent-ID /\n\t\t\t// X-Task-ID. Human-only endpoints (e.g. agent env\n\t\t\t// management) reject requests authenticated this way; see\n\t\t\t// `actorSourceFromRequest`. MUL-2600.\n\t\t\tif strings.HasPrefix(tokenString, \"mat_\") {\n\t\t\t\tif queries == nil {\n\t\t\t\t\thttp.Error(w, `{\"error\":\"invalid token\"}`, http.StatusUnauthorized)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\thash := auth.HashToken(tokenString)\n\t\t\t\ttt, err := queries.GetTaskTokenByHash(r.Context(), hash)\n\t\t\t\tif err != nil {\n\t\t\t\t\tslog.Warn(\"auth: invalid task token\", \"path\", r.URL.Path, \"error\", err)\n\t\t\t\t\thttp.Error(w, `{\"error\":\"invalid token\"}`, http.StatusUnauthorized)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tr.Header.Set(\"X-User-ID\", uuidToString(tt.UserID))\n\t\t\t\tr.Header.Set(\"X-Agent-ID\", uuidToString(tt.AgentID))\n\t\t\t\tr.Header.Set(\"X-Task-ID\", uuidToString(tt.TaskID))\n\t\t\t\tr.Header.Set(\"X-Workspace-ID\", uuidToString(tt.WorkspaceID))\n\t\t\t\t// X-Actor-Source flags the auth path so resolveActor and\n\t\t\t\t// any owner-only handler can deny without re-querying the\n\t\t\t\t// token table. The value \"task_token\" is the only signal\n\t\t\t\t// this header is allowed to carry — strip anything else a\n\t\t\t\t// client tried to send.","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/multica-ai/multica/blob/2c0912b6ec764b373d44eeea1e80f0d9f11ab417/server/internal/middleware/auth.go#L57-L93","documentation":"HTTP 401 from the mat_ (agent task token) branch of the auth middleware when the token prefix matches agent task tokens but the middleware was constructed with a nil database queries object, so the token hash cannot be looked up at all. This is a server-side wiring defect, not a bad token: the handler simply has no way to validate task tokens.","triggerScenarios":"A request with an Authorization: Bearer mat_... token reaches an auth middleware instance built without database queries (e.g. a misconfigured router, a test server, or an embedded deployment that skipped DB wiring).","commonSituations":"Integration tests constructing the middleware without a DB; a partially initialized server during startup races; deployments that intentionally run DB-less (metrics/health) but accidentally route API traffic through them.","solutions":["Fix the server wiring: construct the auth middleware with a non-nil queries object wherever mat_ tokens must be accepted.","If you run the server, check startup logs for database connection failure — queries is nil when DB init failed.","If you are the client, retry against the main API endpoint, not a DB-less auxiliary listener."],"exampleFix":"// before: middleware without DB queries\nr.Use(middleware.Auth(nil, nil))\n\n// after: provide queries\nr.Use(middleware.Auth(queries, cfg))","handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := client.Do(req)\nif err == nil && resp.StatusCode == 401 && isTaskTokenEnv {\n    // nil-queries is a server wiring bug: report to operator; re-claim may mint a fresh token anyway\n}","preventionTips":["Construct the auth middleware with non-nil DB queries wherever mat_ tokens are accepted.","Add a startup check that fails if task-token auth is reachable without a DB.","Cover the mat_ path in integration tests with a real queries object."],"tags":["authentication","server-misconfiguration","http-401","task-token"],"backgroundTag":null,"analyzedSha":"2c0912b6ec764b373d44eeea1e80f0d9f11ab417","analyzedAt":"2026-08-15T13:25:18.241Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}