{"record":{"id":"8a296381a6cb0f35","repo":"chenhg5/cc-connect","slug":"line-channel-secret-and-channel-token-are-require","errorCode":null,"errorMessage":"line: channel_secret and channel_token are required","messagePattern":"line: channel_secret and channel_token are required","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/line/line.go","lineNumber":49,"sourceCode":"type Platform struct {\n\tchannelSecret string\n\tchannelToken  string\n\tallowFrom     string\n\tport          string\n\tcallbackPath  string\n\tbot           *messaging_api.MessagingApiAPI\n\tserver        *http.Server\n\thandler       core.MessageHandler\n\tuserNameCache sync.Map // userID -> display name\n\tgroupNameCache sync.Map // groupID -> group name\n}\n\nfunc New(opts map[string]any) (core.Platform, error) {\n\tsecret, _ := opts[\"channel_secret\"].(string)\n\ttoken, _ := opts[\"channel_token\"].(string)\n\tallowFrom, _ := opts[\"allow_from\"].(string)\n\tif secret == \"\" || token == \"\" {\n\t\treturn nil, fmt.Errorf(\"line: channel_secret and channel_token are required\")\n\t}\n\n\tport, _ := opts[\"port\"].(string)\n\tif port == \"\" {\n\t\tport = \"8080\"\n\t}\n\tpath, _ := opts[\"callback_path\"].(string)\n\tif path == \"\" {\n\t\tpath = \"/callback\"\n\t}\n\n\tcore.CheckAllowFrom(\"line\", allowFrom)\n\treturn &Platform{\n\t\tchannelSecret: secret,\n\t\tchannelToken:  token,\n\t\tallowFrom:     allowFrom,\n\t\tport:          port,\n\t\tcallbackPath:  path,","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/line/line.go#L31-L67","documentation":"line.New validates that the options map contains non-empty channel_secret and channel_token values and fails fast with this error otherwise. The LINE Messaging API requires both to sign/verify webhooks and to authenticate API calls. New returns nil platform and this error when either credential is missing or empty.","triggerScenarios":"Calling line.New(opts) with opts missing the channel_secret or channel_token keys, or with either value set to \"\" (empty string), or with values of a non-string type (type assertion yields \"\").","commonSituations":"config.toml [platforms.line] section missing the fields; environment variable substitution resolving to empty; typo'd key names (channelToken instead of channel_token); passing ints or other non-string types.","solutions":["Add valid channel_secret and channel_token string values from the LINE Developers Console to the options.","Verify the option keys are exactly \"channel_secret\" and \"channel_token\".","Check config.toml interpolation: ensure env vars like ${LINE_CHANNEL_TOKEN} are actually set in the shell/service environment.","Ensure the values are strings, not numbers or other types."],"exampleFix":"// before\nline.New(map[string]any{\"channel_token\": token})\n// after\nline.New(map[string]any{\"channel_secret\": secret, \"channel_token\": token})","handlingStrategy":"validation","validationCode":"// Go: validate options before calling line.New\nfunc validLineOpts(opts map[string]any) error {\n    secret, _ := opts[\"channel_secret\"].(string)\n    token, _ := opts[\"channel_token\"].(string)\n    if secret == \"\" || token == \"\" {\n        return fmt.Errorf(\"line: channel_secret and channel_token must be non-empty strings (got secret=%q, token=%q)\", secret, token)\n    }\n    return nil\n}","typeGuard":"// Go: narrowing check\nsecret, secretOK := opts[\"channel_secret\"].(string)\ntoken, tokenOK := opts[\"channel_token\"].(string)\nif !secretOK || !tokenOK || secret == \"\" || token == \"\" {\n    return errors.New(\"line: channel_secret and channel_token must be non-empty strings\")\n}","tryCatchPattern":null,"preventionTips":["Keep credentials in a config template and validate at startup before registering platforms.","Use consistent snake_case key names matching the platform adapter's expectations.","Fail fast with a startup config check rather than letting empty env substitutions through.","Store tokens in a secret manager instead of hand-edited config to avoid copy errors."],"tags":["line","config","validation"],"backgroundTag":"missing-credentials","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"}