{"record":{"id":"2332e41213d09b0e","repo":"quickwit-oss/quickwit","slug":"the-filename-limit-is-too-small","errorCode":null,"errorMessage":"the filename limit is too small","messagePattern":"the filename limit is too small","errorType":"exception","errorClass":"io::Error (InvalidInput)","httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-common/src/temp_dir.rs","lineNumber":144,"sourceCode":"    }\n\n    /// Constructs the prefix from the parts specified by the join function.\n    /// If parts are small enough they will be simply concatenated with the\n    /// separator character in between. If parts are too large they will\n    /// truncated by replacing the middle of each part with \"..\". The resulting\n    /// string will be at most max_length characters long.\n    fn prefix(&self) -> io::Result<String> {\n        if self.parts.is_empty() {\n            return Ok(String::new());\n        }\n        let separator_count = if self.num_rand_chars > 0 {\n            self.parts.len()\n        } else {\n            self.parts.len() - 1\n        };\n        // We want to preserve at least one letter from each part with separators.\n        if self.max_length < self.parts.len() + separator_count + self.num_rand_chars {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidInput,\n                \"the filename limit is too small\",\n            ));\n        }\n        // Calculate how many characters from the parts we can use in the final string.\n        let len_without_separators = self.max_length - separator_count - self.num_rand_chars;\n        // Calculate how many characters per part can we use.\n        let average_len = len_without_separators / self.parts.len();\n        // Account for the average length may not be a whole number.\n        let mut leftovers = len_without_separators % self.parts.len();\n        // We will have some long parts and some short parts. The short parts (part shorter\n        // than average can \"donate\" their space to the large parts. That will allows us to\n        // use all available space. In this loop we are counting how many characters large\n        // parts can use in addition to the average.\n        for part in &self.parts {\n            if part.len() <= average_len {\n                // Adjust the available length from the parts that are shorter\n                leftovers += average_len - part.len();","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-common/src/temp_dir.rs#L126-L162","documentation":"TempDirectory builds a truncated filename from path parts, separators, and a random suffix while respecting a maximum length. `prefix` requires enough budget to keep at least one character from each part plus separators plus the random chars; if `max_length` is smaller than that minimum, it cannot construct a valid name and throws this io::Error with InvalidInput kind.","triggerScenarios":"Calling TempDirectory's `prefix` builder with a `max_length` too small for the number of path parts — e.g. a very low filename limit combined with a deeply nested or many-part path prefix.","commonSituations":"Filesystems with tight filename limits; users setting an artificially small max filename length; temp prefixes derived from long multi-segment paths on constrained systems.","solutions":["Increase `max_length` on the prefix builder to at least parts + separators + random-char budget.","Reduce the number of parts in the prefix path so each can contribute at least one character.","Fall back to the OS default temp directory naming if the filesystem cannot accommodate the requested limit."],"exampleFix":"// before\nlet prefix = TempPrefix::new(parts).with_max_length(3);\n// after\nlet prefix = TempPrefix::new(parts).with_max_length(parts.len() + parts.len() - 1 + prefix.num_rand_chars());","handlingStrategy":"validation","validationCode":"let min_len = parts.len() + parts.len().saturating_sub(1) + num_rand_chars;\nlet max_length = max_length.max(min_len); // ensure enough budget before calling prefix()","typeGuard":null,"tryCatchPattern":"let prefix = match builder.build() {\n    Ok(p) => p,\n    Err(e) if e.kind() == io::ErrorKind::InvalidInput\n        && e.to_string().contains(\"filename limit is too small\") =>\n    {\n        builder.with_max_length(255).build()? // retry with filesystem max\n    }\n    Err(e) => return Err(e.into()),\n};","preventionTips":["Query the filesystem's max filename length and clamp max_length to it before building the prefix.","Keep temp path prefixes shallow (few parts) on constrained filesystems.","Reserve room for separators and random suffix characters when computing the limit."],"tags":["filesystem","temp-dir","io"],"backgroundTag":"argument-out-of-range","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}