vercel/next.js · error · InstantValidationError

Expected sample param value for segment '${rawSegment}' to b

Error message

Expected sample param value for segment '${rawSegment}' to be a string, got ${typeof paramValue}

What it means

An InstantValidationError from createPathnameFromRouteAndSampleParams() when interpolating a single dynamic segment ([id]). The sample provides a param value that is not a string (e.g. a number or array). Dynamic segments must map to a single string in the sample.

Source

Thrown at packages/next/src/server/app-render/instant-validation/instant-samples.ts:449

            throw new InstantValidationError(
              `Expected sample param value for segment '${rawSegment}' to be an array of strings, got ${typeof paramValue}`
            )
          }
          interpolatedSegments.push(
            ...paramValue.map((v) => encodeURIComponent(v))
          )
          break
        }
        case 'dynamic': {
          let paramValue = params[param.paramName]
          if (paramValue === undefined) {
            // The value for the param was not provided. `usePathname` will detect this and throw
            // before this can surface to userspace. Use `[NAME]` as a placeholder for the param value
            // in case it pops up somewhere unexpectedly.
            paramValue = rawSegment
          } else if (typeof paramValue !== 'string') {
            // NOTE: this happens outside of render, so we don't need `trackMissingSampleErrorAndThrow`
            throw new InstantValidationError(
              `Expected sample param value for segment '${rawSegment}' to be a string, got ${typeof paramValue}`
            )
          }
          interpolatedSegments.push(encodeURIComponent(paramValue))
          break
        }
        case 'catchall-intercepted-(..)(..)':
        case 'catchall-intercepted-(.)':
        case 'catchall-intercepted-(..)':
        case 'catchall-intercepted-(...)':
        case 'dynamic-intercepted-(..)(..)':
        case 'dynamic-intercepted-(.)':
        case 'dynamic-intercepted-(..)':
        case 'dynamic-intercepted-(...)': {
          // TODO(instant-validation-build): i don't know how these are supposed to work, or if we can even get them here
          throw new InvariantError(
            'Not implemented: Validation of interception routes'
          )

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Provide a string value for the dynamic param in the sample.
  2. If the id is numeric in your app, still represent it as a string in the sample.
  3. Verify the segment is a single dynamic segment ([id]) not a catch-all, and shape the value accordingly.
  4. Ensure the sample params object values match each segment's required type.

Example fix

// before (route: /posts/[id])
// unstable_samples: { params: { id: 123 } }

// after
// unstable_samples: { params: { id: '123' } }
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate dynamic-segment sample param shape before build.
function assertDynamicString(paramValue: unknown, name: string) {
  if (paramValue !== undefined && typeof paramValue !== 'string') {
    throw new Error(`param '${name}' must be a string for a dynamic segment`)
  }
}

Type guard

function isString(v: unknown): v is string {
  return typeof v === 'string'
}

Prevention

When it happens

Trigger: During instant validation, the route has a [name] segment and the sample's params object maps name to a non-string. The typeof paramValue !== 'string' check throws.

Common situations: Providing a numeric id in the sample (params: { id: 123 }) instead of a string; accidentally using an array meant for a catch-all route; serializing an object as the param value.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/7ed0d337a619c32f. Report an issue: GitHub.