{"record":{"id":"02110fb95dab6427","repo":"crowdsecurity/crowdsec","slug":"expected-exactly-one-value-for-since","errorCode":null,"errorMessage":"expected exactly one value for 'since'","messagePattern":"expected exactly one value for 'since'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/acquisition/modules/journalctl/config.go","lineNumber":116,"sourceCode":"\n\tfor key, value := range params {\n\t\tswitch key {\n\t\tcase \"filters\":\n\t\t\tfilters = append(filters, value...)\n\t\tcase \"log_level\":\n\t\t\tif len(value) != 1 {\n\t\t\t\treturn errors.New(\"expected exactly one value for 'log_level'\")\n\t\t\t}\n\n\t\t\tlvl, err := log.ParseLevel(value[0])\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tlogLevel = lvl\n\t\tcase \"since\":\n\t\t\tif len(value) != 1 {\n\t\t\t\treturn errors.New(\"expected exactly one value for 'since'\")\n\t\t\t}\n\n\t\t\tsince = value[0]\n\t\tdefault:\n\t\t\treturn fmt.Errorf(\"unsupported key %s in journalctl DSN\", key)\n\t\t}\n\t}\n\n\ts.config = Configuration{\n\t\tDataSourceCommonCfg: configuration.DataSourceCommonCfg{\n\t\t\tMode:     configuration.CAT_MODE,\n\t\t\tLabels:   labels,\n\t\t\tUniqueId: uuid,\n\t\t},\n\t\tFilters: filters,\n\t\tsince:   since,\n\t}\n","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/crowdsecurity/crowdsec/blob/909b5157986a2b2c2163300fdaef5ed01289f7d2/pkg/acquisition/modules/journalctl/config.go#L98-L134","documentation":"In ConfigureByDSN, the since query parameter must appear exactly once since it maps to a single timestamp string passed to journalctl. Duplicate occurrences yield a multi-value slice and are rejected in pkg/acquisition/modules/journalctl/config.go:116.","triggerScenarios":"Calling ConfigureByDSN with a DSN like journalctl://?filters=x&since=2024-01-01&since=2024-06-01.","commonSituations":"Merging default and user-supplied DSN strings that both carry since; query-string builders using repeated-key array semantics; duplicated flags in a wrapper script.","solutions":["Keep only one since value in the DSN: journalctl://?filters=...&since=2024-01-01.","Deduplicate or let later values override earlier ones before constructing the DSN.","Ensure any default since in your tooling is replaced, not appended, when the user provides one."],"exampleFix":"// before\njournalctl://?filters=x&since=2024-01-01&since=2024-06-01\n\n// after\njournalctl://?filters=x&since=2024-06-01","handlingStrategy":"validation","validationCode":"sinceVals := urlVals[\"since\"]\nif len(sinceVals) != 1 {\n    return fmt.Errorf(\"since must appear exactly once, got %d\", len(sinceVals))\n}","typeGuard":"func singleValue(vals url.Values, key string) (string, bool) {\n    v := vals[key]\n    if len(v) != 1 { return \"\", false }\n    return v[0], true\n}","tryCatchPattern":"if err := src.ConfigureByDSN(ctx, dsn); err != nil {\n    if strings.Contains(err.Error(), \"since\") {\n        // rebuild DSN keeping only one since value\n    }\n}","preventionTips":["When merging default and user DSNs, replace rather than append since.","Use a map-based query builder so repeated keys collapse.","Test generated DSNs with url.ParseQuery and assert single values."],"tags":["dsn","query-parameters","journalctl"],"backgroundTag":"invalid-query-parameter","analyzedSha":"909b5157986a2b2c2163300fdaef5ed01289f7d2","analyzedAt":"2026-09-06T12:27:26.012Z","contentChangedAt":"2026-09-06T12:27:26.012Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}