bchavez/Bogus · error · ArgumentException

Can't parse {methodName} because the dataset was not provide

Error message

Can't parse {methodName} because the dataset was not provided in the {nameof(dataSets)} parameter.

What it means

Thrown by Tokenizer.FindDataSetWithMethod (Tokenizer.cs:98) while resolving a {{category.method}} handlebar. The method name was found in the static MustashMethods registry (built once from Faker's [RegisterMustasheMethods] properties), so the category is known, but none of the object instances passed in the dataSets params array has the EXACT declaring type that owns that method. The library throws because reflection invocation needs a target instance and there is no matching one.

Source

Thrown at Source/Bogus/Tokenizer.cs:98

      var fakeVal = mm.Method.Invoke(dataSet, argumentList).ToString();

      var sb = new StringBuilder();
      sb.Append(str, 0, start);
      sb.Append(fakeVal);
      sb.Append(str.Substring(end + 2));

      return Parse(sb.ToString(), dataSets);
   }

   private static object FindDataSetWithMethod(object[] dataSets, string methodName)
   {
      var dataSetType = MustashMethods[methodName].First().Method.DeclaringType;

      var ds = dataSets.FirstOrDefault(o => o.GetType() == dataSetType);

      if( ds == null )
      {
         throw new ArgumentException($"Can't parse {methodName} because the dataset was not provided in the {nameof(dataSets)} parameter.", nameof(dataSets));
      }
      return ds;
   }

   private static void ParseMustashText(string str, int start, int end, out string methodName, out string[] arguments)
   {
      var methodCall = str.Substring(start + 2, end - start - 2)
         .Replace("}}", "")
         .Replace("{{", "");

      var argumentsStart = methodCall.IndexOf("(", StringComparison.Ordinal);
      if (argumentsStart != -1)
      {
         var argumentsString = GetArgumentsString(methodCall, argumentsStart);
         methodName = methodCall.Substring(0, argumentsStart).Trim();
         arguments = argumentsString.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s.Trim()).ToArray();
      }
      else

View on GitHub (pinned to 6ece18c5c2)

Solutions

  1. Prefer Faker.Parse(string) (or Faker<T>.Parse), which forwards every registered dataset, instead of hand-picking a list for Tokenizer.Parse.
  2. If you must call Tokenizer.Parse directly, pass every dataset the template may touch; the error message names the offending {methodName} whose category instance is missing.
  3. Make sure each passed instance's runtime type exactly equals the registered declaring type (no subclasses/wrappers). If you subclassed a dataset, register that subclass type via Tokenizer.RegisterMustashMethods and pass the subclass instance.

Example fix

// before
var s = Tokenizer.Parse("{{internet.email}} ({{name.firstname}})", faker.Name);
// after
var s = Tokenizer.Parse("{{internet.email}} ({{name.firstname}})", faker.Internet, faker.Name);
// or simply
var s = faker.Parse("{{internet.email}} ({{name.firstname}})");
Defensive patterns

Strategy: validation

Validate before calling

// Before calling Tokenizer.Parse directly, confirm every {{cat.method}} in the template
// has its declaring-type instance present in the dataSets you pass.
static void AssertDatasetsProvided(string template, params object[] dataSets)
{
    var present = new HashSet<Type>(dataSets.Select(o => o.GetType()));
    foreach (Match m in Regex.Matches(template, @"\{\{\s*([^.}\s]+)\."))
    {
        var category = m.Groups[1].Value.ToUpperInvariant();
        if (!Tokenizer.MustashMethods.Contains(category)) continue; // different error
        var declType = Tokenizer.MustashMethods[category].First().Method.DeclaringType;
        if (!present.Contains(declType))
            throw new InvalidOperationException($"Template needs dataset {declType.Name} (category '{category.ToLower()}') which was not passed.");
    }
}

Type guard

// Narrow each passed object to its exact registered type (the matcher uses ==, not IsAssignableFrom).
static bool IsRegisteredDataset<TExpected>(object ds) => ds != null && ds.GetType() == typeof(TExpected);

Try / catch

try { var s = Tokenizer.Parse(tpl, datasets); }
catch (ArgumentException ex) when (ex.ParamName == nameof(dataSets) || ex.Message.Contains("dataset was not provided"))
{
    // ex.ParamName is "dataSets" for this specific throw.
    throw new InvalidOperationException($"Template references a dataset not supplied: {tpl}", ex);
}

Prevention

When it happens

Trigger: Calling the low-level Tokenizer.Parse(template, dataSets...) directly and omitting the dataset the template references, e.g. Tokenizer.Parse("{{internet.email}}", faker.Name) passes Name but not Internet, so no object has GetType()==typeof(Internet). Note the match is exact (o.GetType()==dataSetType), so a subclass/wrapper/proxy of a dataset also fails. The public Faker.Parse(string) does NOT trigger this because Faker.cs:81-97 forwards all 15 datasets.

Common situations: Migrating from Faker.Parse to Tokenizer.Parse to inject a custom/seeded dataset subset and forgetting one; sharing one template string across code paths that pass different dataset subsets; passing a mocked or subclassed dataset whose runtime type differs from the registered declaring type; using Random/Date from a different Faker instance than expected.

Related errors


AI-assisted analysis of bchavez/Bogus@6ece18c5c2 (2026-08-13). Data as JSON: /api/errors/bec0ea03af64f1ec. Report an issue: GitHub.