Skip to content

πŸ› Issue: v.fallback() reports success even when type doesn't match schemaΒ #1341

@codeBelt

Description

@codeBelt

I'm using Valibot and ran into an issue where v.fallback() returns a success: true result even when the original value doesn't match the schema type. This makes it difficult to detect and handle type mismatches dynamically β€” for example, when I want to override the fallback value in certain contexts.

πŸ’‘ Scenario

I have a utility function getFeatureFlag that uses a Valibot schema. Depending on where this function is called, I want to override the v.fallback() value if validation fails.

However, because v.fallback() still returns success: true even when the original value fails type validation, I can’t detect that mismatch and apply my override logic.

πŸ” Example

import * as v from 'valibot';

const Schema = v.object({
  myStringFlag: v.fallback(v.string(), 'Hello'),
});

const result = v.safeParse(Schema, {
  myStringFlag: 123, // ❌ wrong type
});

console.log(result);

Output:

{
  typed: true,
  success: true,
  output: { myStringFlag: "Hello" },
  issues: undefined
}

Here, success: true hides the fact that the input type was incorrect (123 instead of string).
I’d expect success to be false or at least to contain an issue indicating that fallback was applied due to a validation failure.

βš™οΈ What I’m Trying to Do

In my use case:

const data = {myStringFlag: 123};

getFeatureFlag('myStringFlag', data, 'My String Override Value'); // Expected: 'My String Override Value'
getFeatureFlag('myStringFlag', data);                             // Expected: 'Hello'

I want to dynamically override the fallback only when the provided data doesn’t match the expected type.

🧩 Proposed Behavior

When the input value fails validation and v.fallback() is triggered:

  • success should be false, or
  • an issue should be added indicating that a fallback was applied due to a type mismatch.

This would allow developers to detect fallback use and implement custom override logic.

βœ… Expected Output Example

{
  typed: true,
  success: false, // <β€” fallback used due to validation failure
  output: { myStringFlag: "Hello" },
  issues: [
    { path: ['myStringFlag'], message: 'Expected string, received number. Using fallback.' }
  ]
}

🧠 Possible Workaround (Current Behavior)

Currently, the workaround is to use v.optional():

const Schema = v.object({
  myStringFlag: v.optional(v.string(), 'Hello'),
});

function getFeatureFlag(key: string, data: any, override?: string) {
  const result = v.safeParse(Schema.entries[key], data[key]);
  
  if (!result.success) {
    return override ?? 'Hello';
  }

  return result.output;
}

But I think v.fallback() is better for my situation than v.optional(). πŸ˜­πŸ‘Ά

πŸ› Playground

https://valibot.dev/playground/?code=JYWwDg9gTgLgBAKjgQwM5wG5wGZQiOAcg2QBtgAjCGQgbgCh6BjCAO1XgGUmALAUxDI4AXkwA6CBQBWfJjAAUAb3pw4IAJ6cYUYKwDmAMVLI9ALnHYypCsiYBreRjEcd%20%20QEoANEQASfUqQQhF70AL7uDMxsHHBQfKgArqTwok6oyNh8AArIUKh88tz8gt7KqhparobGZnAAjABMAMyeYRGMLOwQpHxigXrycYnJ7UA

🧾 Environment

Valibot version: 1.1.0

TypeScript version: 5.9.3

Runtime: Node.js 22.20.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions