{"record":{"id":"a225b9fd854c7ea2","repo":"microg/GmsCore","slug":"streamname-must-be-set","errorCode":null,"errorMessage":"streamName must be set","messagePattern":"streamName must be set","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"play-services-fitness/src/main/java/com/google/android/gms/fitness/data/DataSource.java","lineNumber":266,"sourceCode":"        public Builder setDevice(@NonNull Device device) {\n            this.device = device;\n            return this;\n        }\n\n        /**\n         * The stream name uniquely identifies this particular data source among other data sources of the same type from the same underlying\n         * producer. Setting the stream name is optional, but should be done whenever an application exposes two streams for the same data type, or\n         * when a device has two equivalent sensors.\n         * <p>\n         * The stream name is used by {@link DataSource#getStreamIdentifier()} to make sure the different streams are properly separated when\n         * querying or persisting data.\n         *\n         * @throws IllegalArgumentException If the specified stream name is null.\n         */\n        @NonNull\n        public Builder setStreamName(@NonNull String streamName) {\n            //noinspection ConstantValue\n            if (streamName == null) throw new IllegalArgumentException(\"streamName must be set\");\n            this.streamName = streamName;\n            return this;\n        }\n\n        /**\n         * 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.\n         * {@link DataSource#TYPE_RAW} should be used if the data comes completely from outside of Google Fit.\n         */\n        @NonNull\n        public Builder setType(int type) {\n            this.type = type;\n            return this;\n        }\n    }\n\n    public static final SafeParcelableCreatorAndWriter<DataSource> CREATOR = findCreator(DataSource.class);\n\n}","sourceCodeStart":248,"sourceCodeEnd":284,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-fitness/src/main/java/com/google/android/gms/fitness/data/DataSource.java#L248-L284","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nString name = config.getStreamName(); // may be null\nbuilder.setStreamName(name); // throws when null\n// after\nString name = config.getStreamName();\nif (name == null) name = \"default.step_stream\";\nbuilder.setStreamName(name);","handlingStrategy":"type-guard","validationCode":"if (streamName == null || streamName.isEmpty()) { streamName = \"default.\" + dataType.getName(); }","typeGuard":"String requireStreamName(String s) { return (s != null && !s.isEmpty()) ? s : \"default.stream\"; }","tryCatchPattern":"try { builder.setStreamName(name); } catch (IllegalArgumentException e) { builder.setStreamName(\"default.stream\"); }","preventionTips":["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."],"tags":["android","google-fit","null-argument","validation"],"backgroundTag":"null-argument","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}