{"record":{"id":"e7e8011eb71abe6a","repo":"AlistGo/alist","slug":"pattern-must-contain-one-chunk-token-chunk-or","errorCode":null,"errorMessage":"pattern must contain one chunk token: {chunk} or {chunk:N}","messagePattern":"pattern must contain one chunk token: (.+?) or (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/chunker/util.go","lineNumber":139,"sourceCode":"\nfunc parseNameToken(pattern string) (start, end int, err error) {\n\tnameMagicCount := strings.Count(pattern, \"{name}\")\n\tswitch nameMagicCount {\n\tcase 0:\n\t\treturn 0, 0, errors.New(\"pattern must contain one name token: {name}\")\n\tcase 1:\n\tdefault:\n\t\treturn 0, 0, errors.New(\"pattern must contain exactly one name token: {name}\")\n\t}\n\tstart = strings.Index(pattern, \"{name}\")\n\treturn start, start + len(\"{name}\"), nil\n}\n\nfunc parseChunkToken(pattern string) (start, end, width int, err error) {\n\tchunkMatches := chunkTokenRegexp.FindAllStringSubmatchIndex(pattern, -1)\n\tswitch len(chunkMatches) {\n\tcase 0:\n\t\treturn 0, 0, 0, errors.New(\"pattern must contain one chunk token: {chunk} or {chunk:N}\")\n\tcase 1:\n\tdefault:\n\t\treturn 0, 0, 0, errors.New(\"pattern must contain exactly one chunk token: {chunk} or {chunk:N}\")\n\t}\n\tmatch := chunkMatches[0]\n\tstart = match[0]\n\tend = match[1]\n\tif match[2] >= 0 && match[3] >= 0 {\n\t\twidth, err = strconv.Atoi(pattern[match[2]:match[3]])\n\t\tif err != nil || width <= 0 {\n\t\t\treturn 0, 0, 0, errors.New(\"chunk width in {chunk:N} must be a positive integer\")\n\t\t}\n\t}\n\treturn start, end, width, nil\n}\n\nfunc (d *Chunker) makeChunkName(filePath string, chunkNo int, xactID string) string {\n\tdir, baseName := path.Split(filePath)","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/chunker/util.go#L121-L157","documentation":"parseChunkToken reports this when the chunk name format contains zero chunk tokens. At least one {chunk} or {chunk:N} token is mandatory so each chunk file gets a unique, sortable number embedded in its name.","triggerScenarios":"chunk_name_format set to '{name}.part' or just '{name}' — a pattern with {name} but no {chunk}/{chunk:N}. Fails in setChunkNameFormat during storage Init.","commonSituations":"Users who only want a suffix marker per chunk; forgetting the token after customizing the template; patterns built for a non-chunking driver reused here.","solutions":["Add a chunk token: '{name}_{chunk}' for unpadded or '{name}_{chunk:03}' for zero-padded numbers","Verify the exact spelling — '{Chunk}', '{chunks}', or '{chunk:}' are not matched by chunkTokenRegexp (\\\\{chunk(:[0-9]+)?\\\\})"],"exampleFix":"// before\nchunk_name_format: {name}.part\n// after\nchunk_name_format: {name}.part_{chunk:03}","handlingStrategy":"validation","validationCode":"var chunkToken = regexp.MustCompile(`\\{chunk(:[0-9]+)?\\}`)\nif len(chunkToken.FindAllString(f, -1)) != 1 {\n    return fmt.Errorf(\"chunk name format must contain exactly one {chunk} or {chunk:N} token: %q\", f)\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test the exact token spelling; the driver regex is strict","Cache the validated pattern and reuse it; don't rebuild configs by string surgery"],"tags":["chunker","configuration","validation"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}