{"record":{"id":"95a23215201bbacd","repo":"chenhg5/cc-connect","slug":"attachment-send-is-disabled-by-config","errorCode":null,"errorMessage":"attachment send is disabled by config","messagePattern":"attachment send is disabled by config","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"core/engine.go","lineNumber":105,"sourceCode":"\treplyFooterUsageTimeout  = 1500 * time.Millisecond\n\treplyFooterUsageCacheTTL = 30 * time.Second\n)\n\nconst (\n\tmessageRecallCheckTimeout  = 2 * time.Second\n\tmessageRecallPollInterval  = 2 * time.Second\n\tmessageRecallProbeCooldown = time.Minute\n\trecalledStopLockWait       = 2 * time.Second\n)\n\n// VersionInfo is set by main at startup so that /version works.\nvar VersionInfo string\n\n// CurrentVersion is the semver tag (e.g. \"v1.2.0-beta.1\"), set by main.\nvar CurrentVersion string\n\n// ErrAttachmentSendDisabled indicates that side-channel image/file delivery is disabled by config.\nvar ErrAttachmentSendDisabled = errors.New(\"attachment send is disabled by config\")\n\n// RestartRequest carries info needed to send a post-restart notification.\ntype RestartRequest struct {\n\tSessionKey string `json:\"session_key\"`\n\tPlatform   string `json:\"platform\"`\n}\n\ntype replyFooterUsageCache struct {\n\ttext      string\n\tfetchedAt time.Time\n}\n\n// SaveRestartNotify persists restart info so the new process can send\n// a \"restart successful\" message after startup.\nfunc SaveRestartNotify(dataDir string, req RestartRequest) error {\n\tdir := filepath.Join(dataDir, \"run\")\n\tif err := os.MkdirAll(dir, 0o755); err != nil {\n\t\tslog.Warn(\"SaveRestartNotify: mkdir failed\", \"dir\", dir, \"error\", err)","sourceCodeStart":87,"sourceCodeEnd":123,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/core/engine.go#L87-L123","documentation":"ErrAttachmentSendDisabled is a sentinel error in the engine indicating that side-channel delivery of images/files is turned off in config. When a message contains attachments but attachmentSendEnabled is false, the engine refuses to deliver them instead of silently dropping them. It is a deliberate policy error, not an infrastructure failure.","triggerScenarios":"Calling the engine's send paths (core/engine.go:11195 and core/engine.go:11273) with non-empty images or files slices while e.attachmentSendEnabled is false, i.e. the config disabled attachment sending.","commonSituations":"Operator set attachment_send=false (or equivalent) in config.toml for security/compliance; a platform adapter forwards rich messages with images; a user sends a screenshot to the bot; tests like TestSendToSessionWithAttachmentsRespectsDisabledAttachmentSend exercise this path.","solutions":["Enable attachment sending in config.toml (set the attachment-send option to true) and restart cc-connect.","Strip or skip images/files before calling the send path when attachment sending is known to be disabled.","Handle the sentinel with errors.Is(err, core.ErrAttachmentSendDisabled) and surface a user-friendly 'attachments not allowed' message."],"exampleFix":"// before\nif err := e.sendToSessionWithAttachments(ctx, key, text, images, files); err != nil {\n    return err\n}\n// after\nif err := e.sendToSessionWithAttachments(ctx, key, text, images, files); err != nil {\n    if errors.Is(err, core.ErrAttachmentSendDisabled) {\n        return e.Reply(ctx, replyCtx, \"Attachments are disabled on this server.\")\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"if !e.attachmentSendEnabled && (len(images) > 0 || len(files) > 0) {\n    // skip attachment path up front\n}","typeGuard":null,"tryCatchPattern":"if errors.Is(err, core.ErrAttachmentSendDisabled) {\n    // inform user attachments are disabled; do not retry\n}","preventionTips":["Check the attachment-send config flag before sending messages that may contain images/files.","Use errors.Is against the sentinel rather than string comparison.","Document in config.example.toml that attachment sending is opt-in."],"tags":["config","attachments","engine","feature-flag"],"backgroundTag":"feature-not-enabled","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}