Crosstalk-Solutions/project-nomad · warning · Error
Filename is required
Error message
Filename is required
What it means
Thrown by DocsService.parseFile when called with an empty/undefined filename. The method immediately requires a truthy _filename before resolving it against the docs directory. Note this is a plain Error that gets wrapped into 'Error parsing file: ...' by the enclosing catch.
Source
Thrown at admin/app/services/docs_service.ts:68
// Filter out attribute-undefined errors which may be caused by emojis and special characters
const criticalErrors = errors.filter((e) => e.error.id !== 'attribute-undefined')
if (criticalErrors.length > 0) {
logger.error('Markdoc validation errors:', errors.map((e) => JSON.stringify(e.error)).join(', '))
throw new Error('Markdoc validation failed')
}
return Markdoc.transform(ast, config)
} catch (error) {
logger.error('Error parsing Markdoc content:', error)
throw new InternalServerErrorException(`Error parsing content: ${(error as Error).message}`)
}
}
async parseFile(_filename: string) {
try {
if (!_filename) {
throw new Error('Filename is required')
}
const filename = _filename.endsWith('.md') ? _filename : `${_filename}.md`
// Prevent path traversal — resolved path must stay within the docs directory
const basePath = path.resolve(this.docsPath)
const fullPath = path.resolve(path.join(this.docsPath, filename))
if (!fullPath.startsWith(basePath + path.sep)) {
throw new Error('Invalid document slug')
}
const fileExists = await getFileStatsIfExists(fullPath)
if (!fileExists) {
throw new Error(`File not found: ${filename}`)
}
const fileStream = await getFile(fullPath, 'stream')
if (!fileStream) {View on GitHub (pinned to 0bd1c6f4f9)
Solutions
- Make the slug required in the controller (ParseSlugPipe / @IsNotEmpty validation) so NestJS rejects it before the service
- Default or reject empty slugs at the call site before invoking parseFile
- Fix the caller that produces undefined (check frontend URL construction)
Example fix
// before
@Get(':slug')
content(@Param('slug') slug?: string) {
return this.docs.content(slug) // may pass undefined
}
// after
@Get(':slug')
content(@Param('slug', ParseSlugPipe) slug: string) {
return this.docs.content(slug)
} Defensive patterns
Strategy: validation
Validate before calling
if (!slug || typeof slug !== 'string' || slug.trim() === '') {
throw new BadRequestException('slug is required')
}
await docsService.parseFile(slug) Type guard
const isValidSlugRequest = (slug: unknown): slug is string => typeof slug === 'string' && slug.trim().length > 0
Try / catch
try {
await docsService.parseFile(slug)
} catch (e) {
if ((e as Error).message.includes('Filename is required'))
throw new BadRequestException('Document slug is required')
throw e
} Prevention
- Make the slug a required route param with a validation pipe
- Add class-validator @IsNotEmpty() on DTO fields feeding parseFile
- Write a unit test for the empty-slug path
When it happens
Trigger: Calling parseFile(''), parseFile(undefined), or parseFile(null) — e.g. a route handler where the slug path parameter is optional and was omitted.
Common situations: Optional route params not validated at the controller level, undefined slug from a frontend that builds the URL from an empty state, destructuring mistakes passing the wrong variable.
Understand the failure class
Background: Missing required parameter errors: what 'X is required' and 'the required X param is missing' mean, and how to fix them — this error's family across 27 libraries.
Related errors
- Invalid document slug
- Error parsing file: ${(error as Error).message}
- Error parsing content: ${(error as Error).message}
- File not found: ${filename}
- Failed to read file stream: ${filename}
AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27).
Data as JSON: /api/errors/f333dd251ba6d795.
Report an issue: GitHub.