{"record":{"id":"f9cd1ccecb551093","repo":"microg/GmsCore","slug":"datatype-must-be-set","errorCode":null,"errorMessage":"dataType must be set","messagePattern":"dataType must be set","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"play-services-fitness/src/main/java/com/google/android/gms/fitness/data/DataSource.java","lineNumber":199,"sourceCode":"    /**\n     * A builder that can be used to construct new data source objects. In general, a built data source should be saved in memory to avoid the cost\n     * of re-constructing it for every request.\n     */\n    public static class Builder {\n        private DataType dataType;\n        private Device device;\n        private Application application;\n        private int type = -1;\n        private String streamName = \"\";\n\n        /**\n         * Finishes building the data source and returns a DataSource object.\n         *\n         * @throws IllegalStateException If the builder didn't have enough data to build a valid data source.\n         */\n        @NonNull\n        public DataSource build() {\n            if (dataType == null) throw new IllegalStateException(\"dataType must be set\");\n            if (type < 0) throw new IllegalStateException(\"type must be set\");\n            return new DataSource(dataType, type, device, application, streamName);\n        }\n\n        /**\n         * Sets the package name for the application that is recording or computing the data. Used for data sources that aren't built into the platform\n         * (local sensors and BLE sensors are built-in). It can be used to identify the data source, to disambiguate between data from different\n         * applications, and also to link back to the original application for a detailed view.\n         */\n        @NonNull\n        public Builder setAppPackageName(@NonNull String packageName) {\n            Application application = Application.GMS_APP;\n            this.application = Constants.GMS_PACKAGE_NAME.equals(packageName) ? Application.GMS_APP : new Application(packageName);\n            return this;\n        }\n\n        /**\n         * Sets the package name for the application that is recording or computing the data based on the app's context. This method should be","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/microg/GmsCore/blob/157c9d86ac46c195a86c2f15ab55c84036223f95/play-services-fitness/src/main/java/com/google/android/gms/fitness/data/DataSource.java#L181-L217","documentation":"Thrown by DataSource.Builder.build() when no DataType has been set. A DataSource must declare what kind of data it produces (e.g. TYPE_STEP_COUNT_DELTA); without a DataType the resulting DataSource would be invalid, so the builder refuses to construct it.","triggerScenarios":"Calling DataSource.Builder.build() without ever calling setDataType(DataType) on that builder.","commonSituations":"Copy-pasted builder code where the setDataType line was deleted; conditional config where the data type comes from a null variable; refactors that split builder construction across methods and skip the dataType step.","solutions":["Call setDataType(DataType.AGGREGATE_...) or the appropriate DataType before build().","If the data type is dynamic, assert/validate it is non-null before building.","Wrap the dataType in an Optional and throw a clear app-level error early if missing.","Check that you are building the intended Builder instance (not a fresh one that lost the setDataType call)."],"exampleFix":"// before\nDataSource src = new DataSource.Builder()\n    .setType(DataSource.TYPE_RAW)\n    .build(); // throws\n// after\nDataSource src = new DataSource.Builder()\n    .setDataType(DataType.TYPE_STEP_COUNT_DELTA)\n    .setType(DataSource.TYPE_RAW)\n    .build();","handlingStrategy":"validation","validationCode":"if (builderDataType == null) throw new IllegalStateException(\"setDataType must be called before build()\");","typeGuard":"boolean sourceReady(DataSource.Builder b, DataType dt) { return dt != null; }","tryCatchPattern":"try { src = dataSourceBuilder.build(); } catch (IllegalStateException e) { throw new ConfigException(\"DataSource missing dataType\", e); }","preventionTips":["Always chain .setDataType(...) first in DataSource builders.","Centralize DataSource construction in one factory method.","Unit-test the factory so missing fields fail in CI.","Never pass possibly-null DataType variables into the builder."],"tags":["android","google-fit","missing-required-field","builder"],"backgroundTag":"missing-required-argument","analyzedSha":"157c9d86ac46c195a86c2f15ab55c84036223f95","analyzedAt":"2026-09-06T17:27:33.892Z","contentChangedAt":"2026-09-06T17:27:33.892Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}