Skip to content

pbjs --filter fails to resolve dependencies in packages deeper than one segment #2416

Description

@twoRoger

Expected behavior

pbjs --filter should keep the selected messages and all of their transitive dependencies, regardless of how deeply the dependency's package is nested.

For the reproduction below, the filtered output should contain example.Response, example.values.Value, example.values.Meta and example.values.Kind, and should not contain example.UnusedRoot or example.values.UnusedValue.

Actual behavior

The filter cannot resolve a dependency whose package has more than one segment. It reports a warning and pbjs then writes the completely unfiltered root, so nothing is filtered at all:

The filter not work, please check whether the file is correct: package not foud values.Value

The exit code is 0 and filtered.json contains every message from both files, including UnusedRoot and UnusedValue.

The cause is in cli/util.js. A dependency's name is rebuilt from its immediate parent:

var packageName = field.resolvedType.parent.name;
var typeName = field.resolvedType.name;
var fullName = packageName ? `${packageName}.${typeName}` : typeName;

For .example.values.Value the immediate parent is only values, so the reconstructed name is values.Value. That name is then split into exactly two segments, which cannot address anything below package.Message.

This is the same defect reported in #1854, which was closed as inactive on 2026-06-09 with a request to open a fresh issue if it is still relevant. It is still present in 8.7.2 / protobufjs-cli 2.6.2.

Minimal reproduction

values.proto:

syntax = "proto3";

package example.values;

message Value {
  Meta meta = 1;
  Kind kind = 2;
}

message Meta {
  string description = 1;
}

enum Kind {
  KIND_UNSPECIFIED = 0;
  KIND_PRIMARY = 1;
}

message UnusedValue {
  string value = 1;
}

root.proto:

syntax = "proto3";

package example;

import "values.proto";

message Response {
  values.Value value = 1;
}

message UnusedRoot {
  string value = 1;
}

filter.json:

{ "messageNames": ["example.Response"] }

Command:

npx pbjs -t json --filter filter.json -o filtered.json root.proto

Output written to filtered.json:

{
  "nested": {
    "example": {
      "nested": {
        "Response": { "fields": { "value": { "type": "values.Value", "id": 1 } } },
        "UnusedRoot": { "fields": { "value": { "type": "string", "id": 1 } } },
        "values": {
          "nested": {
            "Value": { "fields": { "meta": { "type": "Meta", "id": 1 }, "kind": { "type": "Kind", "id": 2 } } },
            "Meta": { "fields": { "description": { "type": "string", "id": 1 } } },
            "Kind": { "values": { "KIND_UNSPECIFIED": 0, "KIND_PRIMARY": 1 } },
            "UnusedValue": { "fields": { "value": { "type": "string", "id": 1 } } }
          }
        }
      }
    }
  }
}

A single-segment package such as package example; works, which is why the existing --filter test does not catch this.

protobufjs version

8.7.2

protobufjs-cli version, if applicable

2.6.2

Environment, if applicable

Node 24.13.0, CLI

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions