emberjs/ember.js · error · Error

You didn't provide enough string/numeric parameters to satis

Error message

You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route ${name}. Missing params: ${missingParams}

What it means

router_js throws this from createParamHandlerInfo when building a transition by route name but too few string/numeric params were provided to fill every dynamic segment. Each dynamic segment must be satisfied by a supplied param or a context object; the missing ones are listed in the message.

Source

Thrown at packages/router_js/lib/transition-intent/named-transition-intent.ts:249

        (oldHandlerInfo && name === oldHandlerInfo.name && oldHandlerInfo.params) || {};

      let peek = objects[objects.length - 1];
      let paramName = names[numNames]!;
      if (isParam(peek)) {
        params[paramName] = String(objects.pop());
      } else {
        // If we're here, this means only some of the params
        // were string/number params, so try and use a param
        // value from a previous handler.
        if (oldParams.hasOwnProperty(paramName)) {
          params[paramName] = oldParams[paramName];
        } else {
          missingParams.push(paramName);
        }
      }
    }
    if (missingParams.length > 0) {
      throw new Error(
        `You didn't provide enough string/numeric parameters to satisfy all of the dynamic segments for route ${name}.` +
          ` Missing params: ${missingParams}`
      );
    }

    return new UnresolvedRouteInfoByParam(this.router, name, names, params);
  }
}

View on GitHub (pinned to 26f97246a8)

Solutions

  1. Provide a context object (model) instead of raw params so serialize() can derive them.
  2. Ensure the model hook resolves (don't return undefined) so all dynamic segment keys exist in params.
  3. Fix the route's serialize() to return keys matching every dynamic segment name.
  4. Pass explicit params: transitionTo('post', params.post_id) with a defined string/number.

Example fix

// before
this.transitionTo('post'); // :post_id unsatisfied
// after
this.transitionTo('post', this.store.findRecord('post', id));
Defensive patterns

Strategy: validation

Validate before calling

function canSerialize(route, model) {
  const params = route.serialize?.(model, route.paramsFor?.(route.routeName)) ?? {};
  const missing = Object.keys(route.fullRouteName ? dynamicNames : {}).filter(k => params[k] == null);
  return missing.length === 0 ? null : missing;
}
const missing = canSerialize(postRoute, post);
if (missing) throw new Error('missing params: ' + missing);

Type guard

function hasAllParams(params, names) { return names.every(n => typeof params[n] === 'string' || typeof params[n] === 'number'); }

Try / catch

router.transitionTo('post', post).catch(e => {
  if (e.message.includes("didn't provide enough string/numeric parameters")) {
    router.transitionTo('posts.index');
  } else throw e;
});

Prevention

When it happens

Trigger: transitionTo('post', undefined) or transitionTo('post') where route 'post' has :post_id and no context object is given; params map from serialize() missing keys; supplying objects where strings/numbers are required so they don't count as params.

Common situations: Model hooks returning undefined so serialize() yields no id; link-to with a promise that hasn't resolved; renaming dynamic segments in the router map without updating serializers/callers.

Related errors


AI-assisted analysis of emberjs/ember.js@26f97246a8 (2026-09-01). Data as JSON: /api/errors/9497a1924fa28ca6. Report an issue: GitHub.