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

  1. Make the slug required in the controller (ParseSlugPipe / @IsNotEmpty validation) so NestJS rejects it before the service
  2. Default or reject empty slugs at the call site before invoking parseFile
  3. 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

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


AI-assisted analysis of Crosstalk-Solutions/project-nomad@0bd1c6f4f9 (2026-08-27). Data as JSON: /api/errors/f333dd251ba6d795. Report an issue: GitHub.