{"record":{"id":"273d298fb5e70811","repo":"Tencent/WeKnora","slug":"schedule-attachment-parsing-w","errorCode":null,"errorMessage":"schedule attachment parsing: %w","messagePattern":"schedule attachment parsing: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/application/service/temporary_document.go","lineNumber":207,"sourceCode":"\t\treturn nil, fmt.Errorf(\"create attachment record: %w\", err)\n\t}\n\tif s.resourceCatalog != nil {\n\t\tif err := s.resourceCatalog.Bind(ctx, resourceRef, types.ResourceOwnerTemporaryDocument, document.ID, types.ResourceRelationSourceFile); err != nil {\n\t\t\t_ = s.repo.DeleteScoped(ctx, tenantID, sessionID, document.ID)\n\t\t\t_ = s.fileService.DeleteFile(ctx, resourceRef)\n\t\t\treturn nil, fmt.Errorf(\"bind attachment resource: %w\", err)\n\t\t}\n\t}\n\tpayload, _ := json.Marshal(types.TemporaryDocumentTaskPayload{TenantID: tenantID, DocumentID: document.ID})\n\tqueue, _ := types.QueueForTaskType(types.TypeTemporaryDocumentProcess)\n\tif _, err := s.taskEnqueuer.Enqueue(\n\t\tasynq.NewTask(types.TypeTemporaryDocumentProcess, payload),\n\t\tasynq.Queue(queue), asynq.MaxRetry(2), asynq.Timeout(10*time.Minute),\n\t); err != nil {\n\t\t_ = s.repo.MarkFailed(ctx, tenantID, document.ID, \"failed to schedule document parsing\")\n\t\tdocument.Status = types.TemporaryDocumentStatusFailed\n\t\tdocument.ErrorMessage = \"failed to schedule document parsing\"\n\t\treturn document, fmt.Errorf(\"schedule attachment parsing: %w\", err)\n\t}\n\treturn document, nil\n}\n\nfunc (s *temporaryDocumentService) supportsExtension(ctx context.Context, tenantID uint64, ext string) bool {\n\tif _, ok := temporaryDocumentExtensions[ext]; ok {\n\t\treturn true\n\t}\n\tif s.documentReader == nil {\n\t\treturn false\n\t}\n\tvar overrides map[string]string\n\tif tenant, err := s.tenantService.GetTenantByID(ctx, tenantID); err == nil && tenant != nil {\n\t\toverrides = tenant.ParserEngineConfig.ToOverridesMap()\n\t}\n\tengines, err := s.documentReader.ListEngines(ctx, overrides)\n\tif err != nil {\n\t\treturn false","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/Tencent/WeKnora/blob/988cbb03305e055d8ebb7d46d9ac6cc0803cd074/internal/application/service/temporary_document.go#L189-L225","documentation":"Create persists the temporary document and then enqueues an asynq task for parsing; if enqueueing fails, the document is marked failed and the enqueue error is wrapped with this prefix. The root cause is the asynq broker (usually Redis) being unreachable or rejecting the task.","triggerScenarios":"Redis down or misconfigured for asynq; invalid queue name; payload marshal failure; task option conflicts (queue/timeout) rejected by the broker.","commonSituations":"Redis connection limits exhausted in prod; wrong REDIS_ADDR env; queue name typo after a rename; network partition between app and broker.","solutions":["Check the asynq broker/Redis connectivity (redis-cli ping from the app host)","Verify the queue name matches a queue a server is consuming","Inspect the wrapped error (errors.Unwrap / %w chain) for the underlying asynq cause","Implement a retry or fallback synchronous path for scheduling, and alert on repeated MarkFailed records"],"exampleFix":"// before\nclient.Enqueue(task, asynq.Queue(\"tempdoc\"))\n// after\nif err := client.Enqueue(task, asynq.Queue(queue)); err != nil {\n    logger.Error(\"enqueue failed\", \"err\", err, \"queue\", queue)\n    return fmt.Errorf(\"schedule attachment parsing: %w\", err)\n}","handlingStrategy":"try-catch","validationCode":"if err := broker.Ping(); err != nil { return fmt.Errorf(\"task broker unavailable: %w\", err) }","typeGuard":null,"tryCatchPattern":"doc, err := svc.Create(ctx, req)\nvar wrapped *fmt.wrapError\nif err != nil && errors.As(err, &wrapped) && strings.HasPrefix(err.Error(), \"schedule attachment parsing:\") {\n    // broker failure: surface 503 and/or retry Create\n}","preventionTips":["Health-check Redis/asynq before accepting uploads","Pin queue names in config shared by producer and consumer","Alert on documents stuck in failed status","Set sensible asynq retry/dead-letter options"],"tags":["asynq","task-queue","redis"],"backgroundTag":"task-enqueue-failed","analyzedSha":"988cbb03305e055d8ebb7d46d9ac6cc0803cd074","analyzedAt":"2026-09-02T14:41:08.344Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}