{"record":{"id":"ab50cb4ecc602f87","repo":"dotnet/aspnetcore","slug":"fileextensions-validator-requires-a-non-empty-ext","errorCode":null,"errorMessage":"FileExtensions validator requires a non-empty \"extensions\" parameter.","messagePattern":"FileExtensions validator requires a non-empty \"extensions\" parameter\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Validation/Validators/FileExtensions.ts","lineNumber":12,"sourceCode":"// Licensed to the .NET Foundation under one or more agreements.\n// The .NET Foundation licenses this file to you under the MIT license.\n\nimport { ValidationContext, ValidationResult, Validator, pass, fail } from '../ValidationTypes';\n\n// Validates that the filename ends with an allowed extension (case-insensitive).\n// Extensions param is comma-separated with dot prefix (e.g. \".png,.jpg,.gif\").\n// Throws if the mandatory `extensions` parameter is missing.\nexport const fileExtensionsValidator: Validator = (context: ValidationContext): ValidationResult => {\n  const { value, params } = context;\n  if (!params.extensions) {\n    throw new Error('FileExtensions validator requires a non-empty \"extensions\" parameter.');\n  }\n\n  if (!value) {\n    return pass();\n  }\n\n  // Build regex from comma-separated extensions, stripping dots and escaping regex metacharacters.\n  const extensions = params.extensions.split(',')\n    .map(ext => ext.trim().replace(/^\\./, ''))\n    .filter(ext => ext.length > 0)\n    .map(ext => ext.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&'))\n    .join('|');\n\n  if (!extensions) {\n    return pass();\n  }\n\n  return new RegExp(`\\\\.(${extensions})$`, 'i').test(value) ? pass() : fail();","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Validation/Validators/FileExtensions.ts#L1-L30","documentation":"The FileExtensions validator (client-side counterpart for [FileExtensions]) needs an 'extensions' parameter — a comma-separated, dot-prefixed list of allowed extensions (e.g. '.png,.jpg'). Without it the validator cannot build its match regex and throws before evaluating the value. The check runs first so a misconfigured rule fails loudly.","triggerScenarios":"Thrown at line 12 when params.extensions is falsy. Occurs when the validator is invoked via a data-val-fileextensions-extensions attribute (or programmatic registration) that is missing or empty.","commonSituations":"A [FileExtensions(Extensions = \".png,.jpg\")] attribute whose client-side data-val-fileextensions-extensions attribute was stripped by a sanitizer or never emitted; a hand-built file input missing the data-val attribute; tag helper misconfiguration on the input tag.","solutions":["Ensure the file input renders data-val-fileextensions-extensions=\".png,.jpg\" (or your allowed set).","Confirm the C# property has [FileExtensions(Extensions = \".png,.jpg,.gif\")] so the tag helper emits the attribute.","If registering the validator manually, pass { extensions: '.png,.jpg' } in params.","Check no HTML sanitizer is stripping data-* attributes from file inputs."],"exampleFix":"<!-- before -->\n<input type=\"file\" name=\"Avatar\" data-val=\"true\" data-val-fileextensions=\"Only images\" />\n<!-- after -->\n<input type=\"file\" name=\"Avatar\" data-val=\"true\" data-val-fileextensions=\"Only images\" data-val-fileextensions-extensions=\".png,.jpg,.gif\" />","handlingStrategy":"validation","validationCode":"function fileExtensionsConfigured(params: any): boolean {\n  return !!params && typeof params.extensions === 'string' && params.extensions.length > 0;\n}","typeGuard":"function hasExtensionsParam(p: unknown): p is { extensions: string } {\n  return !!p && typeof (p as any).extensions === 'string' && (p as any).extensions.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Apply [FileExtensions(Extensions = \".png,.jpg\")] on the model property.","Verify rendered file inputs include data-val-fileextensions-extensions.","Ensure HTML sanitizers preserve data-* attributes.","Pass required params when registering validators manually."],"tags":["blazor","validation","fileextensions","form-validation","misconfiguration"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}