microg/GmsCore · error · IllegalArgumentException
streamName must be set
Error message
streamName must be set
What it means
Thrown by DataSource.Builder.setStreamName when a null stream name is passed. The stream identifier distinguishes multiple data sources of the same type, and the API requires it to be a non-null String. Unlike build(), this is an IllegalArgumentException — the argument itself is invalid, not the builder state.
Source
Thrown at play-services-fitness/src/main/java/com/google/android/gms/fitness/data/DataSource.java:266
public Builder setDevice(@NonNull Device device) {
this.device = device;
return this;
}
/**
* The stream name uniquely identifies this particular data source among other data sources of the same type from the same underlying
* producer. Setting the stream name is optional, but should be done whenever an application exposes two streams for the same data type, or
* when a device has two equivalent sensors.
* <p>
* The stream name is used by {@link DataSource#getStreamIdentifier()} to make sure the different streams are properly separated when
* querying or persisting data.
*
* @throws IllegalArgumentException If the specified stream name is null.
*/
@NonNull
public Builder setStreamName(@NonNull String streamName) {
//noinspection ConstantValue
if (streamName == null) throw new IllegalArgumentException("streamName must be set");
this.streamName = streamName;
return this;
}
/**
* Sets the type of the data source. {@link DataSource#TYPE_DERIVED} should be used if any other data source is used in generating the data.
* {@link DataSource#TYPE_RAW} should be used if the data comes completely from outside of Google Fit.
*/
@NonNull
public Builder setType(int type) {
this.type = type;
return this;
}
}
public static final SafeParcelableCreatorAndWriter<DataSource> CREATOR = findCreator(DataSource.class);
}View on GitHub (pinned to 157c9d86ac)
Solutions
- Provide a descriptive constant stream name, e.g. setStreamName("my_app.step_counter").
- Null-check or requireNonNull the source value before calling setStreamName.
- If the name comes from config, fail fast with a clear error when config is absent.
- Use a default fallback name when the configured name is null/blank.
Example fix
// before String name = config.getStreamName(); // may be null builder.setStreamName(name); // throws when null // after String name = config.getStreamName(); if (name == null) name = "default.step_stream"; builder.setStreamName(name);
Defensive patterns
Strategy: type-guard
Validate before calling
if (streamName == null || streamName.isEmpty()) { streamName = "default." + dataType.getName(); } Type guard
String requireStreamName(String s) { return (s != null && !s.isEmpty()) ? s : "default.stream"; } Try / catch
try { builder.setStreamName(name); } catch (IllegalArgumentException e) { builder.setStreamName("default.stream"); } Prevention
- Use compile-time constants for stream names instead of nullable variables.
- requireNonNull config-sourced names at startup.
- Never pass results of nullable lookups straight into setStreamName.
- Prefer Kotlin non-null types or Objects.requireNonNull at boundaries.
When it happens
Trigger: Passing a null String to setStreamName, typically from a variable that is null: a missing config value, an unresolvable resource string, or a null return from a lookup.
Common situations: Stream names read from Settings/RemoteConfig that were never configured; null results from string resources or database lookups; Kotlin/Java interop where a platform type silently allowed null.
Related errors
- Field not found
- deleteAll was set to true but keys were also provided
- Element in keys cannot be null or empty
- deleteAll=true but keys are provided
- retrieveAll was set to true but other constraint(s) was also
AI-assisted analysis of microg/GmsCore@157c9d86ac (2026-09-06).
Data as JSON: /api/errors/a225b9fd854c7ea2.
Report an issue: GitHub.