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
Expected behavior
pbjs --filtershould 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.Metaandexample.values.Kind, and should not containexample.UnusedRootorexample.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 exit code is 0 and
filtered.jsoncontains every message from both files, includingUnusedRootandUnusedValue.The cause is in
cli/util.js. A dependency's name is rebuilt from its immediate parent:For
.example.values.Valuethe immediate parent is onlyvalues, so the reconstructed name isvalues.Value. That name is then split into exactly two segments, which cannot address anything belowpackage.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:root.proto:filter.json:{ "messageNames": ["example.Response"] }Command:
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--filtertest 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